<?php

namespace App\Models;

use App\Http\Common\Lib\Common;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class LotteryRecord extends BaseModel
{
	//
	protected $validatorName = 'LotteryRecord';

	/**
	 * 推荐记录对应的比赛
	 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
	 */
	public function match()
	{
		return $this->belongsTo('App\Models\Match', 'match_id', 'id');
	}

	public function user()
	{
		return $this->belongsTo('App\Models\User', 'user_id', 'id');
	}

	/**
	 * 更新比赛记录
	 * @param $matchId
	 * @return array
	 */
	public function updateRecords($matchId)
	{
		$matchModel = new Match();
		$match = $matchModel->where('id', $matchId)->where('status', 1)->first();
		if (!$match) {
			return Common::dataFormat(config('statusInfo.status.notFound'), config('statusInfo.msg.notFound'));
		}
		//$matchScores = explode(':',$match->score);
		$matchResults = explode(',', $match->result);
		if ($match->records) {
			foreach ($match->records as $record) {
				$sp1 = explode(',', $record->sp1);
				$sp2 = explode(',', $record->sp2);
				$results = explode(',', $record->result);
				$odds = 0;
				foreach ($results as $result) {
					$result = intval($result);
					if (in_array($result, $matchResults)) {
						switch ($result) {
							case 1:
								//胜
								$odds += $sp1[0];
								break;
							case 2:
								//平
								$odds += $sp1[1];
								break;
							case 3:
								//负
								$odds += $sp1[2];
								break;
							case 4:
								//让胜
								$odds += $sp2[0];
								break;
							case 5:
								//让平
								$odds += $sp2[1];
								break;
							case 6:
								//让负
								$odds += $sp2[2];
								break;
						}
					}
				}
				$record->odds = $odds;
				$res = $record->save();
				if ($res) {
					if ($odds > 0 && $record->user) {
						$preScore = $record->user->score;
						if ($record->user->increment('score', $odds)) {
							ScoreRecord::addRecord($record->user_id, $preScore, $odds, '预测比赛命中', 1);
						}
					}
				}
			}
		}
		return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'));
	}

	/**
	 * 列表
	 * @param int $page
	 * @param int $pageSize
	 * @param string $session
	 * @param string $search
	 * @return array
	 */
	public function pages($page = 1, $pageSize = 20, $session = '', $search = '')
	{
		$fields = ['lr.id', 'lr.user_id', 'lr.match_id', 'lr.sp1', 'lr.sp2', 'lr.result', 'lr.odds', 'lr.status', 'm.session', 'm.number', 'm.host', 'm.guest', 'm.balls', 'm.score', 'm.result as match_result', 'm.status as match_status', 'm.die_time', 'u.nickname', 'u.account'];
		$query = $this->from('lottery_records as lr')
			->leftJoin('matches as m', 'lr.match_id', '=', 'm.id')
			->leftJoin('users as u', 'lr.user_id', '=', 'u.id')
			->select($fields)
			->where('m.status', '>', -1)
			->where('lr.status', 1);
		if ($search) {
			$query->where(function ($ql) use ($search) {
				$ql->orWhere('m.host', 'like', '%' . $search . '%')->orWhere('m.guest', 'like', '%' . $search . '%');
			});
		} else {
			if (!$session) {
				$session = date('Ymd');
			}
		}
		if ($session) {
			$query->where('m.session', $session);
		}
		$count = $query->count();
		if ($count == 0) {
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => $count, 'totalPages' => 0, 'pages' => null]);
		}
		$pages = $query->orderBy('m.session', 'asc')
			->orderBy('m.number', 'asc')
			->skip(($page - 1) * $pageSize)
			->take($pageSize)
			->get();
		$lastTime = strtotime($session) + 3600 * 24 - 5 * 60;
		foreach ($pages as $value) {
			$value->sp1 = explode(',', $value->sp1);
			$value->sp2 = explode(',', $value->sp2);
			$value->result = explode(',', $value->result);
			$value->match_result = explode(',', $value->match_result);
			$value->die_time = $value->die_time < $lastTime ? $value->die_time : $lastTime;
			$value->die_time = date('Y-m-d H:i');
		}
		$totalPages = ceil($count / $pageSize);
		return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => $count, 'totalPages' => $totalPages, 'pages' => $pages]);
	}

	/**
	 * 用户推荐记录
	 * @param $userId
	 * @param int $page
	 * @param int $pageSize
	 * @param string $start
	 * @param string $end
	 * @param string $search
	 * @return array
	 */
	public function userRecords($userId, $page = 1, $pageSize = 20, $start = '', $end = '', $search = '')
	{
		$fields = ['lr.id', 'lr.user_id', 'lr.match_id', 'lr.sp1', 'lr.sp2', 'lr.result', 'lr.odds', 'lr.status', 'm.session', 'm.number', 'm.host', 'm.guest', 'm.balls', 'm.score', 'm.result as match_result', 'm.status as match_status', 'm.die_time', 'u.nickname', 'u.account'];
		$query = $this->from('lottery_records as lr')
			->leftJoin('matches as m', 'lr.match_id', '=', 'm.id')
			->leftJoin('users as u', 'lr.user_id', '=', 'u.id')
			->select($fields)
			->where('lr.user_id', $userId)
			->where('m.status', '>', -1)
			->where('lr.status', 1);
		if ($start) {
			$query->where('m.session', '>=', $start);
		}
		if ($end) {
			$query->where('m.session', '<=', $end);
		}
		if ($search) {
			$query->where(function ($ql) use ($search) {
				$ql->orWhere('m.host', 'like', '%' . $search . '%')->orWhere('m.guest', 'like', '%' . $search . '%');
			});
		}
		$count = $query->count();
		if ($count == 0) {
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => $count, 'totalPages' => 0, 'pages' => null]);
		}
		$pages = $query->orderBy('m.session', 'desc')
			->orderBy('m.number', 'asc')
			->skip(($page - 1) * $pageSize)
			->take($pageSize)
			->get();

		foreach ($pages as $value) {
			$lastTime = strtotime($value->session) + 3600 * 24 - 5 * 60;
			$value->sp1 = explode(',', $value->sp1);
			$value->sp2 = explode(',', $value->sp2);
			$value->result = explode(',', $value->result);
			$value->match_result = explode(',', $value->match_result);
			$value->die_time = $value->die_time < $lastTime ? $value->die_time : $lastTime;
			$value->die_time = date('Y-m-d H:i');
		}
		$totalPages = ceil($count / $pageSize);
		return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => $count, 'totalPages' => $totalPages, 'pages' => $pages]);
	}

	/**
	 * 推荐统计
	 * @param $userId
	 * @param string $start
	 * @param string $end
	 * @param string $type
	 * @return mixed
	 */
	public function statistic($userId, $start = '', $end = '', $type = 'month')
	{
		if (!$end) {
			$end = date('Ymd');
		}
		$query = $this->from('lottery_records as lr')
			->join('matches as m', 'lr.match_id', '=', 'm.id')
			->join('users as u', 'lr.user_id', '=', 'u.id')
			->where('lr.user_id', $userId)
			->where('m.status', 1)
			->where('lr.status', 1)
			->where('m.session', '<=', $end);
		if (!$start) {
			$type = strtolower($type);
			$endTime = strtotime($end);
			switch ($type) {
				case 'week':
					$startTime = $endTime - 3600 * 24 * 7;
					break;
				case 'month':
					$startTime = $endTime - 3600 * 24 * 30;
					break;
				case 'quarter':
					$startTime = $endTime - 3600 * 24 * 30 * 3;
					break;
				default:
					$startTime = $endTime - 3600 * 24 * 30;
					break;
			}
			$start = date('Ymd', $startTime);
		}
		$query = $query->where('m.session', '>=', $start);
		$info = $query->groupBy('u.id')->groupBy('u.account')->groupBy('u.nickname')->first([
			'u.id',
			'u.account',
			'u.nickname',
			DB::raw('SUM(lr.pay_score) as pay_scores'),
			DB::raw('COUNT(lr.id) as total_number'),
			DB::raw('SUM(lr.odds) as total_odds'),
		]);
		if (!$info) {
			$userModel = new User();
			$user = $userModel->where('id', $userId)->select(['id', 'account', 'nickname'])->first();
			$data = ['id' => 0, 'account' => '', 'nickname' => '', 'pay_scores' => 0, 'total_number' => 0, 'total_odds' => 0];
			if ($user) {
				$data['id'] = $user->id;
				$data['account'] = $user->account;
				$data['nickname'] = $user->nickname;
			}
			$info = (object)$data;
		}
		$hitNumber = $query->where('lr.odds', '>', 0)->count('u.id');
		$info->hit_number = $hitNumber;
		$rate = 0;
		if ($info->total_number > 0) {
			$rate = number_format(($hitNumber / $info->total_number) * 100, 2);
		}
		$info->total_odds = number_format($info->total_odds, 2);
		$info->rate = $rate;
		return $info;

	}

	/**
	 * 推荐统计数据
	 * @param $userId
	 * @param string $start
	 * @param string $end
	 * @param string $type
	 * @return mixed
	 */
	public function statisticData($userId, $start = '', $end = '', $type = 'month')
	{
		if (!$end) {
			$end = date('Ymd');
		}
		$fields = ['lr.id', 'm.session', 'm.number', 'lr.odds'];
		$query = $this->from('lottery_records as lr')
			->leftJoin('matches as m', 'lr.match_id', '=', 'm.id')
			->leftJoin('users as u', 'lr.user_id', '=', 'u.id')
			->where('lr.user_id', $userId)
			->where('m.status', 1)
			->where('lr.status', 1)
			->where('m.session', '<=', $end);
		if (!$start) {
			$type = strtolower($type);
			$endTime = strtotime($end);
			switch ($type) {
				case 'week':
					$startTime = $endTime - 3600 * 24 * 7;
					break;
				case 'month':
					$startTime = $endTime - 3600 * 24 * 30;
					break;
				case 'quarter':
					$startTime = $endTime - 3600 * 24 * 30 * 3;
					break;
				default:
					$startTime = $endTime - 3600 * 24 * 30;
					break;
			}
			$start = date('Ymd', $startTime);
		}
		$query->where('m.session', '>=', $start);
		$data = $query->select($fields)->orderBy('m.session', 'asc')->orderBy('m.number', 'asc')->get();
		if($data){
			foreach ($data as $value){
				$value->odds = number_format($value->odds,2);
			}
		}
		return $data;
	}

	/**
	 * 比赛推荐
	 * @param int $page
	 * @param int $pageSize
	 * @param string $session
	 * @param int $rate
	 * @param int $number
	 * @param string $type
	 * @return array
	 */
	public function recommendMatches($page = 1, $pageSize = 20, $session = '', $rate = 66, $number = 10, $score=1,$type = 'month')
	{
		$userModel = new User();
		$users = $userModel->pickUsers($session, $rate, $number, $score,$type, true);
		$userIds = $users->pluck('id')->toArray();
		if (empty($userIds)) {
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => 0, 'totalPages' => 0, 'pages' => null]);
		}
		$fields = ['lr.id', 'lr.user_id', 'lr.match_id', 'lr.sp1', 'lr.sp2', 'lr.result', 'lr.odds', 'lr.status', 'm.session', 'm.number', 'm.host', 'm.guest', 'm.balls', 'm.score', 'm.result as match_result', 'm.status as match_status', 'm.die_time', 'u.nickname', 'u.account'];
		$query = $this->from('lottery_records as lr')
			->leftJoin('matches as m', 'lr.match_id', '=', 'm.id')
			->leftJoin('users as u', 'lr.user_id', '=', 'u.id')
			->where('m.status', '>', -1)
			->where('lr.status', 1)
			->where('m.session', $session)
			->whereIn('lr.user_id', $userIds)
			->select($fields);
		//dd([$query->toSql(),$userIds,$session]);
		$count = $query->count();
		//dd($count);
		if ($count == 0) {
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => 0, 'totalPages' => 0, 'pages' => null]);
		}
		$pages = $query->orderBy('m.number', 'asc')
			->skip(($page - 1) * $pageSize)
			->take($pageSize)
			->get();
		$lastTime = strtotime($session) + 3600 * 24 - 60 * 5;
		foreach ($pages as $value) {
			$value->sp1 = explode(',', $value->sp1);
			$value->sp2 = explode(',', $value->sp2);
			$value->result = explode(',', $value->result);
			$value->match_result = explode(',', $value->match_result);
			$value->die_time = $value->die_time < $lastTime ? $value->die_time : $lastTime;
			$value->die_time = date('Y-m-d H:i');
		}
		$totalPages = ceil($count / $pageSize);
		return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), ['page' => $page, 'pageSize' => $pageSize, 'totalCount' => $count, 'totalPages' => $totalPages, 'pages' => $pages]);

	}

	public function add($input, $isAdmin = false)
	{
		$validateRes = $this->validateData($input, 'add');
		if ($validateRes['status'] != config('statusInfo.status.success')) {
			return Common::dataFormat($validateRes['status'], $validateRes['msg']);
		}
		if (empty($input['result'])) {
			return Common::dataFormat(config('statusInfo.status.fail'), '没有推荐结果');
		}
		$userModel = new User();
		$user = $userModel->where('id', $input['user_id'])->where('status', 1)->first();
		if (!$user) {
			return Common::dataFormat(config('statusInfo.status.notFound'), '用户不存在');
		}
		$matchModel = new Match();
		$match = $matchModel->where('id', $input['match_id'])->where('status', 2)->first();
		if (!$match) {
			return Common::dataFormat(config('statusInfo.status.notFound'), '比赛不存在');
		}
		$resultNum = count($input['result']);
		$baseScore = 1;
		if ($resultNum > 1) {
			$baseScore = 0.75;
		}
		$payScore = number_format($resultNum * $baseScore, 2);
		if (!$isAdmin) {
			$lastTime = strtotime($match->session) + 24 * 3600 - 5 * 60;
			$lastTime = $lastTime < $match->die_time ? $lastTime : $match->die_time;
			if ($lastTime < time()) {
				return Common::dataFormat(config('statusInfo.status.fail'), '超过推荐时间');
			}
			if ($payScore > $user->score) {
				return Common::dataFormat(config('statusInfo.status.fail'), '用户积分不足');
			}

		}

		$record = new LotteryRecord();
		$record->user_id = $input['user_id'];
		$record->match_id = $input['match_id'];
		$record->sp1 = $match->sp1;
		$record->sp2 = $match->sp2;
		$record->result = implode(',', $input['result']);
		$record->pay_score = $payScore;
		$record->status = 1;
		$res = $record->save();
		if ($res) {
			//用户分数减少
			$preScore = $user->score;
			if ($user->decrement('score', $payScore)) {
				ScoreRecord::addRecord($user->id, $preScore, $payScore * (-1), '预测比赛，积分扣除', -1);
			}
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), [$this->primaryKey => $record->id]);
		} else {
			return Common::dataFormat(config('statusInfo.status.fail'), config('statusInfo.msg.fail'));
		}
	}

	public function edit($input, $isAdmin = false)
	{
		$validateRes = $this->validateData($input, 'add');
		if ($validateRes['status'] != config('statusInfo.status.success')) {
			return Common::dataFormat($validateRes['status'], $validateRes['msg']);
		}
		if (empty($input['result'])) {
			return Common::dataFormat(config('statusInfo.status.fail'), '没有推荐结果');
		}
		//用户
		$userModel = new User();
		$user = $userModel->where('id', $input['user_id'])->where('status', 1)->first();
		if (!$user) {
			return Common::dataFormat(config('statusInfo.status.notFound'), '用户不存在');
		}
		//比赛
		$matchModel = new Match();
		$match = $matchModel->where('id', $input['match_id'])->where('status', 2)->first();
		if (!$match) {
			return Common::dataFormat(config('statusInfo.status.notFound'), '比赛不存在');
		}
		//记录
		$record = $this->where($this->primaryKey, $input['id'])->first();
		if (!$record) {
			return Common::dataFormat(config('statusInfo.status.notFound'), '推荐记录不存在');
		}
		$resultNum = count($input['result']);
		$baseScore = 1;
		if ($resultNum > 1) {
			$baseScore = 0.75;
		}
		$payScore = number_format($resultNum * $baseScore, 2);
		if (!$isAdmin) {
			$lastTime = strtotime($match->session) + 24 * 3600 - 5 * 60;
			$lastTime = $lastTime < $match->die_time ? $lastTime : $match->die_time;
			if ($lastTime < time()) {
				return Common::dataFormat(config('statusInfo.status.fail'), '超过推荐时间');
			}
		}
		$record->match_id = $input['match_id'];
		$record->sp1 = $match->sp1;
		$record->sp2 = $match->sp2;
		$record->result = implode(',', $input['result']);
		$record->pay_score = $payScore;
		$record->status = 1;
		$res = $record->save();
		if ($res) {
			return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'));
		} else {
			return Common::dataFormat(config('statusInfo.status.fail'), config('statusInfo.msg.fail'));
		}
	}

	/**
	 * 详情
	 * @param $id
	 * @return array
	 */
	public function detail($id)
	{
		$record = $this->where($this->primaryKey, $id)->first();
		if (!$record) {
			return Common::dataFormat(config('statusInfo.status.notFound'), config('statusInfo.msg.notFound'));
		}
		$record->sp1 = explode(',', $record->sp1);
		$record->sp2 = explode(',', $record->sp2);
		$record->result = explode(',', $record->result);
		$match = $record->match;
		if ($match) {
			$match->sp1 = explode(',', $match->sp1);
			$match->sp2 = explode(',', $match->sp2);
			$match->result = explode(',', $match->result);
			$match->odds = explode(',', $match->odds);
			$lastTime = strtotime($match->session) + 24 * 3600 - 5 * 60;
			$lastTime = $lastTime < $match->die_time ? $lastTime : $match->die_time;
			$match->die_time = date('Y-m-d H:i:s', $lastTime);
		}
		return Common::dataFormat(config('statusInfo.status.success'), config('statusInfo.msg.success'), $record);
	}
}
